﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Text;
using dis.sys.hw1.ClientProxy;
using dis.sys.hw1.Contract;
using dis.sys.hw1.Service;
using dis.sys.hw1.Model;

namespace dis.sys.h21.HotelSearchServiceHost
{
    class Program
    {
        private static readonly ServiceLog _log = new ServiceLog(typeof(Program), true);
        private const int ClientsPort = 0;
        private const int HotelsPort = 1;

        static void Main(string[] args)
        {
            if (args.Count() < 2)
            {
                Console.WriteLine("Invalid usage, please use: HotelSearchService.exe <clients port> <hotels port>");
                return;
            }

            string hotelsEndPointAddress = "http://localhost:" + args[HotelsPort] + "/Services";
            string clientsEndPointAddress = "http://localhost:" + args[ClientsPort] + "/Services";


            //var service = new HotelSearchService();

            var hotelServiceProxies = new ConcurrentDictionary<string,DelegateHotelServiceProxy>();
            var queryCache = new ConcurrentDictionary<Tuple<long, long, double, double>, Tuple<DateTime, IList<Hotel>>>();
            using (var webhost = new WebServiceHost(new HotelSearchService(hotelServiceProxies, queryCache), new Uri(clientsEndPointAddress)))
            {
                webhost.AddServiceEndpoint(typeof(ISearchService), new WebHttpBinding(), "HotelSearch");

                webhost.Open();

                _log.Info("Endpoint opened at: " + clientsEndPointAddress + "/HotelSearch");

                using (var host = new ServiceHost(new HotelRegistrationService(hotelServiceProxies, queryCache), new Uri(hotelsEndPointAddress)))
                {
                    var smb = new ServiceMetadataBehavior
                                  {
                                      HttpGetEnabled = true,
                                      MetadataExporter = {PolicyVersion = PolicyVersion.Policy15}
                                  };
                    host.Description.Behaviors.Add(smb);
                    // Add MEX endpoint to listen to registration requests
                    host.AddServiceEndpoint(
                        ServiceMetadataBehavior.MexContractName,
                        MetadataExchangeBindings.CreateMexHttpBinding(),
                        "mex"
                        );

                    host.AddServiceEndpoint(typeof (IRegistrationService), new BasicHttpBinding(), "HotelRegistration");

                    host.Open();

                    _log.Info("Endpoint opened at: " + hotelsEndPointAddress + "/HotelRegistration");

                    Console.ReadLine();
                }
            }
        }
    }
}
